[2017_Inc0gnito] [REV] leon¶
문제내용¶
Please.. come.. Service available at: Here Source code available at: Here
문제 풀이¶
strace는 애플리케이션들이 사용하는 system call과 signal 등을 추적해서 성능 저하를 일으키는 부분은 없는지, 에러가 나는 부분은 없는지를 확인하는데 사용하는 디버깅 툴이다.
strace를 통해 해당 바이너리 파일을 확인해보자.
$ strace ./leon
execve("./leon", ["./leon"], [/* 36 vars */]) = 0
brk(NULL) = 0xc72000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f07e912e000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=54768, ...}) = 0
mmap(NULL, 54768, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f07e9120000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\t\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1864888, ...}) = 0
mmap(NULL, 3967392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f07e8b42000
mprotect(0x7f07e8d01000, 2097152, PROT_NONE) = 0
mmap(0x7f07e8f01000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bf000) = 0x7f07e8f01000
mmap(0x7f07e8f07000, 14752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f07e8f07000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f07e911f000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f07e911e000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f07e911d000
arch_prctl(ARCH_SET_FS, 0x7f07e911e700) = 0
mprotect(0x7f07e8f01000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ) = 0
mprotect(0x7f07e9130000, 4096, PROT_READ) = 0
munmap(0x7f07e9120000, 54768) = 0
ptrace(PTRACE_TRACEME, 0, 0x1, NULL) = -1 EPERM (Operation not permitted)
exit_group(1) = ?
+++ exited with 1 +++
뭔가 파일이 존재하지 않는다고 하면서 ENOENT 에러를 뱉고, ptrace로 인해 EPERM 에러를 뱉는 것을 확인할 수 있습니다.
objdump는 GNU 바이너리 유틸리티의 일부로서, 라이브러리, 컴파일된 오브젝트 모듈, 공유 오브젝트 파일, 독립 실행파일등의 바이너리 파일들의 정보를 보여주는 프로그램이다. objdump는 ELF 파일을 어셈블리어로 보여주는 역어셈블러로 사용될 수 있다.
$ objdump -d ./leon | grep \<ptrace@plt\>
0000000000400660 <ptrace@plt>:
400818: e8 43 fe ff ff callq 400660 <ptrace@plt>
ptrace 주소를 확인하였으니, 해당 주소 이전에 브레이크를 걸어보자.
gdb-peda$ b *0x40081d
Breakpoint 1 at 0x40081d
gdb-peda$ r
Starting program: /home/joizel/leon
[----------------------------------registers-----------------------------------]
RAX: 0xffffffffffffffff
RBX: 0x0
RCX: 0x7ffff7b0adee (<ptrace+78>: cmp rax,0xfffffffffffff000)
RDX: 0xffffffffffffff98
RSI: 0x0
RDI: 0x0
RBP: 0x7fffffffe210 --> 0x4008a0 (<__libc_csu_init>: push r15)
RSP: 0x7fffffffe1b0 --> 0x2a ('*')
RIP: 0x40081d (<main+54>: cmp rax,0xffffffffffffffff)
R8 : 0xffffffff
R9 : 0x7ffff7de7ab0 (<_dl_fini>: push rbp)
R10: 0x0
R11: 0x282
R12: 0x400680 (<_start>: xor ebp,ebp)
R13: 0x7fffffffe2f0 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x213 (CARRY parity ADJUST zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x40080e <main+39>: mov edi,0x0
0x400813 <main+44>: mov eax,0x0
0x400818 <main+49>: call 0x400660 <ptrace@plt>
=> 0x40081d <main+54>: cmp rax,0xffffffffffffffff
0x400821 <main+58>: jne 0x40082d <main+70>
0x400823 <main+60>: mov edi,0x1
0x400828 <main+65>: call 0x400670 <exit@plt>
0x40082d <main+70>: mov rdx,QWORD PTR [rip+0x20088c] # 0x6010c0 <stdin@@GLIBC_2.2.5>
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe1b0 --> 0x2a ('*')
0008| 0x7fffffffe1b8 --> 0x601080 ("INC0{doesn't_seem_to_be_write_something..}")
0016| 0x7fffffffe1c0 --> 0x7fffffffe1d0 --> 0x2
0024| 0x7fffffffe1c8 --> 0x4007df (<_init_+24>: pop rbp)
0032| 0x7fffffffe1d0 --> 0x2
0040| 0x7fffffffe1d8 --> 0x4008ed (<__libc_csu_init+77>: add rbx,0x1)
0048| 0x7fffffffe1e0 --> 0xff000000
0056| 0x7fffffffe1e8 --> 0x0
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Breakpoint 1, 0x000000000040081d in main ()
gdb-peda$
스택상에서 플래그 확인